#include "table.h"
#include "bprinter/table_printer.h"
#include <iostream>

#include "deployment.h"
#include "template_set.h"
#include "ship_template.h"
#include "ship.h"
#include "fleet.h"

#include <vector>
#include <array>
#include <string>

using namespace std;

namespace Table {
	void print( const TemplateSet& _set ) {
		bprinter::TablePrinter tp(&cout);

		tp.AddColumn(_set.name, 15 );
		tp.AddColumn("Template Name", 20);
		tp.AddColumn("Template Class", 30);
		tp.AddColumn("Template Cost", 15);

		vector<array<string,3>> summaries = _set.getShipTemplateSummaries();

		tp.PrintHeader();
		
		int counter = 1;
		string temp;
		bool atLeastOne = false;
		for ( auto &it : summaries ) {
			temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2];
			counter++;
			atLeastOne = true;
		}

		if ( ! atLeastOne ) tp << "" << bprinter::endl();
		
		tp.PrintFooter();

		cout << "\n";
	}

	//-----------------------------
	//------- SHIPTEMPLATE  -------
	//-----------------------------

	void print( const ShipTemplate& _ship ) {
		bprinter::TablePrinter tp(&cout);

		tp.AddColumn(_ship.name, 15 );
		tp.AddColumn("Slot Side", 15);
		tp.AddColumn("Slot Type", 15);
		tp.AddColumn("Loadable", 11);
		tp.AddColumn("Cost", 10);

		vector<array<string,4>> summaries = _ship.getSlotTemplateSummaries();

		tp.PrintHeader();
		
		int counter = 1;
		string temp, side;
		if ( summaries.begin() != summaries.end() ) side = (*summaries.begin())[0];
		for ( auto &it : summaries ) {
			if ( side != it[0] ) {
				side = it[0];
				tp << "" << bprinter::endl();
			}
			temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2] << it[3];
			counter++;
		}
		
		tp << "" << bprinter::endl();
		tp << "" << "" << "HP" << std::to_string(_ship.getMaxHp()) << HP_SHIP_COST(_ship.getMaxHp());
		tp << "" << "" << "TOWER SLOTS" << _ship.getTowers() << TOWER_SLOT_COST(_ship.getTowers());
		tp << "" << bprinter::endl();

		tp << "" << "" << "" << "Grand Total" << _ship.getCost();
		
		tp.PrintFooter();

		cout << "\n";

	}

	//-----------------------------
	//---------- SHIP -------------
	//-----------------------------

	void print( const Ship& _ship ) {
		bprinter::TablePrinter tp(&cout);

		tp.AddColumn(_ship.name, 15 );
		tp.AddColumn("Slot Side", 15);
		tp.AddColumn("Slot Type", 15);
		tp.AddColumn("Loadable", 11);
		tp.AddColumn("Slot Loadout", 20);
		tp.AddColumn("Loadout Cost", 15);

		// Total 75

		vector<array<string,5>> summaries = _ship.getSlotLoadoutSummaries();

		tp.PrintHeader();
		
		int counter = 1;
		string temp, side;
		if ( summaries.begin() != summaries.end() ) side = (*summaries.begin())[0];
		for ( auto &it : summaries ) {
			if ( side != it[0] ) {
				side = it[0];
				tp << "" << bprinter::endl();
			}
			temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2] << it[3] << it[4];
			counter++;
		}
		
		tp << "" << bprinter::endl();
		// string hp = std::to_string(_ship.getActualHp()) + "/" +
					// std::to_string(_ship.getShipTemplate()->getMaxHp());
		// tp << "" << "" << "Current HP" << hp << "--";

		vector<int> towers = _ship.getTowerLoadouts();

		int j = 1;
		for ( int tow : towers ) {
			tp << "" << "" << ("CONTR. TOWER " + std::to_string(j)) << "" << STRING_TOWER(tow) << TOWER_COST(tow);
			j++;
		}
		if ( j == 1 )
			tp << "" << "" << "CONTR. TOWER" << "" << "None Available" << "";

		tp << "" << "" << "" << "Thrust" << _ship.getThrust() << "0";
		tp << "" << bprinter::endl();

		tp << "" << "" << "" << "" << "Loadout Total" << _ship.getLoadoutCost();
		tp << "" << "" << "" << "" << "Grand Total" << _ship.getCost();
		
		tp.PrintFooter();
		cout << "\n";
	}

	//-----------------------------
	//--------- SHIPSTAT ----------
	//-----------------------------

	void printStat( const Ship& _ship ) {
		bprinter::TablePrinter tp(&cout);

		tp.AddColumn(_ship.name, 15 );
		tp.AddColumn("Slot Side", 20);
		tp.AddColumn("Slot Type", 10);
		tp.AddColumn("Slot Actual HP", 15);
		tp.AddColumn("Slot Total HP", 15);

		// Total 75

		vector<array<string,4>> summaries = _ship.getSlotStatusSummaries();

		tp.PrintHeader();
		
		int counter = 1;
		string temp, side;
		if ( summaries.begin() != summaries.end() ) side = (*summaries.begin())[0];
		for ( auto &it : summaries ) {
			if ( side != it[0] ) {
				side = it[0];
				tp << "" << bprinter::endl();
			}
			temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2] << it[3];
			counter++;
		}
		
		tp << "" << bprinter::endl();

		vector<bool> noTowers = _ship.getTowerStatuses();

		int j = 1;
		for ( bool noTow : noTowers ) {
			tp << "" << "" << "" << ("CONTR. TOWER " + std::to_string(j)) << (noTow ? "Inactive" : "Active" );
			j++;
		}
		if ( j == 1 )
			tp << "" << "" << "" << "CONTR. TOWERS" << "None Available";

		tp.PrintFooter();
		cout << "\n";

	}
	//-----------------------------
	//----------  FLEET -----------
	//-----------------------------

	void print( const Fleet & _fleet ) {
		bprinter::TablePrinter tp(&cout);

		tp.AddColumn(_fleet.name, 15 );
		tp.AddColumn("Ship Name", 20);
		tp.AddColumn("Ship Template", 20);
		tp.AddColumn("Cost", 10);

		vector<array<string,3>> summaries = _fleet.getShipSummaries();

		tp.PrintHeader();
		
		int counter = 1;
		for ( auto &it : summaries ) {
			string temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2];
			counter++;
		}
		
		tp << "" << bprinter::endl();

		tp << "" << "" << "Grand Total" << _fleet.getCost();
		
		tp.PrintFooter();

		cout << "\n";
	}

	//-----------------------------
	//-------- DEPLOYMENT ---------
	//-----------------------------

	void print( const Deployment & _dep ) {
		{
			bprinter::TablePrinter tp(&cout);

			tp.AddColumn(_dep.name, 15 );
			tp.AddColumn("Fleet Names", 20);
			tp.AddColumn("Fleet Captain", 20);
			tp.AddColumn("Ships Number", 15);
			tp.AddColumn("Cost", 10);
			// TOTAL = 80

			// Fleets
			vector<array<string,4>> fleetSummaries = _dep.getFleetSummaries();
			tp.PrintHeader();	
			int counter = 1;
			for ( auto &it : fleetSummaries ) {
				string temp = "[" + std::to_string(counter) + "]";
				tp << temp << it[0] << it[1] << it[2] << it[3];
				counter++;
			}	
			tp << "" << bprinter::endl();
			tp << "" << "" << "" << "Grand Total" << _dep.getCost();
		}
		{
		bprinter::TablePrinter tp(&cout);
		tp.AddColumn("", 15 );
		tp.AddColumn("Ship Names", 20);
		tp.AddColumn("Template Names", 20);
		tp.AddColumn("Fleet Name", 15);
		tp.AddColumn("Cost", 10);
		// TOTAL = 65

		// Ships
		vector<array<string,4>> shipSummaries = _dep.getShipSummaries();
		tp.PrintHeader();	
		int counter = 1;
		for ( auto &it : shipSummaries ) {
			string temp = "[" + std::to_string(counter) + "]";
			tp << temp << it[0] << it[1] << it[2] << it[3];
			counter++;
		}	
		tp << "" << bprinter::endl();
		tp << "" << "" << "" << "Grand Total" << _dep.getCost();
		tp.PrintFooter();
		cout << "\n";
		}

	}	
}
